package com.example.everying.service.order.impl;

import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.everying.constant.ChatMessageConstant;
import com.example.everying.constant.OrderConstants;
import com.example.everying.framework.websocket.service.WebSocketChatService;
import com.example.everying.mapper.order.TransferRecordMapper;
import com.example.everying.model.dto.chat.ConversationDto;
import com.example.everying.model.dto.order.TransferRecordDto;
import com.example.everying.model.entity.chat.ChatMessagesEntity;
import com.example.everying.model.entity.order.TransferRecord;
import com.example.everying.model.entity.user.UserBalanceEntity;
import com.example.everying.model.entity.user.UserBalanceTransactionEntity;
import com.example.everying.model.entity.user.UserEntity;
import com.example.everying.model.vo.chat.ChatMessageVo;
import com.example.everying.model.vo.user.UserInfoVo;
import com.example.everying.service.chat.ChatConversationService;
import com.example.everying.service.chat.ChatMessagesService;
import com.example.everying.service.order.TransferRecordService;
import com.example.everying.service.user.UserBalanceService;
import com.example.everying.service.user.UserBalanceTransactionService;
import com.example.everying.service.user.UserService;
import com.example.everying.utils.CampusException;
import com.example.everying.utils.RandomUtil;
import com.example.everying.utils.Result;
import com.example.everying.utils.WeChatUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.List;

@Slf4j
@Service
public class TransferRecordServiceImpl extends ServiceImpl<TransferRecordMapper, TransferRecord> implements TransferRecordService {

    @Autowired
    private UserBalanceService userBalanceService;
    @Autowired
    private UserService userService;
    @Autowired
    private UserBalanceTransactionService userBalanceTransactionService;
    @Autowired
    private ChatConversationService chatConversationService;
    @Autowired
    private ChatMessagesService chatMessagesService;


    /**
     * @param dto
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Result<?> addTransferRecord(TransferRecordDto dto) {
        if (dto == null) {
            return Result.fail("参数错误");
        }
        log.info("开始创建转账记录 {}", dto);
        TransferRecord record = new TransferRecord();
        BeanUtils.copyProperties(dto, record);
        record.setId(RandomUtil.generateId());
        if (record.getToUserId() == null) {
            return Result.fail("请选择收款用户");
        } else {
            UserInfoVo userInfoVo = userService.getUserById(record.getToUserId());
            if (userInfoVo == null) {
                return Result.fail("为保障资金安全，请核实对方身份后再进行转账");
            }
            if (userInfoVo.getId().equals(record.getFromUserId())) {
                return Result.fail("不能给自己转账");
            }
            if (userInfoVo.getState() != 1) {
                return Result.fail("收款用户已禁用");
            }
            if (userInfoVo.getIsDelete() == 1) {
                return Result.fail("收款用户已删除");
            }
            if (userInfoVo.getPhone().isEmpty()){
                return Result.fail("收款用户账号异常");
            }
            chatConversationService.checkConversationByTransfer(record.getFromUserId(), record.getToUserId());
            log.info("收款用户 {}", userInfoVo);
        }
        if (record.getFromUserId() == null) {
            return Result.fail("请选择付款用户");
        } else {
            UserInfoVo userInfoVo = userService.getUserById(record.getFromUserId());
            if (userInfoVo == null) {
                return Result.fail("付款用户不存在");
            }
            log.info("付款用户 {}", userInfoVo);
        }
        if (record.getAmount() == null) {
            return Result.fail("请输入金额");
        }
        if (record.getAmount().compareTo(BigDecimal.valueOf(0.01)) < 0) {
            return Result.fail("金额不能小于0.01");
        }
        // 校验余额
        UserBalanceEntity fromUserBalance = userBalanceService.getBalanceByUserId(record.getFromUserId());
        if (fromUserBalance == null || fromUserBalance.getAvailableAmount().compareTo(record.getAmount()) < 0) {
            return Result.fail("余额不足");
        }

        // 创建转账记录
        record.setTxNo(WeChatUtil.generateOrderTradeNumber(OrderConstants.TRANSACTION_TYPE_PREFIX_TRANSFER));
        record.setStatus("0");
        record.setCreateTime(LocalDateTime.now());
        record.setUpdateTime(LocalDateTime.now());
        if (!this.save(record)) {
            return Result.fail("创建转账记录失败");
        }
        // 开始转账
        if (dto.getPayPassword().isEmpty()) {
            return Result.fail("支付密码不能为空");
        }
        // 校验密码
        boolean isVerified = userService.verifyPassword(record.getFromUserId(), dto.getPayPassword());
        if (!isVerified) {
            return Result.fail("支付密码错误");
        }
        boolean isDeducted = startDeduction(record);
        if (!isDeducted) {
            log.info("用户 {} 扣款失败", record.getFromUserId());
            return Result.fail("扣款失败");
        }
        // 异步发送转账消息
        saveMessage(record);
        return Result.ok();
    }

    // 开始扣款
    private boolean startDeduction(TransferRecord record) {
        BigDecimal amount = record.getAmount();
        String userId = record.getFromUserId();
        log.info("开始扣款，用户id{},金额{}", userId, amount);
        boolean isDeducted = userBalanceService.deductBalance(userId, amount);
        if (isDeducted) {
            UserBalanceEntity userBalance = userBalanceService.getBalanceByUserId(userId);
            boolean deductedTxSuccess = createAndSaveTransaction(userId, record.getTxNo(), amount,
                    userBalance.getAvailableAmount().subtract(amount),
                    OrderConstants.TYPE_USER_EXPENSE, "用户转账付款",
                    OrderConstants.USER_TYPE_USER, OrderConstants.ORDER_TYPE_TRANSFER
            );
            if (!deductedTxSuccess) {
                log.info("用户 {} 扣款交易记录保存失败", userId);
                throw new CampusException("扣款失败", 201);
            }
        }

        log.info("开始给用户加钱，用户id{},金额{}", record.getToUserId(), amount);
        boolean isAdded = userBalanceService.addBalance(record.getToUserId(), amount);
        if (isAdded) {
            UserBalanceEntity platformBalance = userBalanceService.getBalanceByUserId(record.getToUserId());
            boolean addedTxSuccess = createAndSaveTransaction(record.getToUserId(), record.getTxNo(),
                    amount, platformBalance.getAvailableAmount().add(amount),
                    OrderConstants.TYPE_USER_INCOME, "用户转账收款",
                    OrderConstants.USER_TYPE_USER, OrderConstants.ORDER_TYPE_TRANSFER
            );
            if (!addedTxSuccess) {
                log.info("平台用户 {} 加款交易记录保存失败", record.getToUserId());
                throw new CampusException("扣款失败", 201);
            }
        }
        return isDeducted && isAdded;
    }

    // 公共方法：创建并保存交易记录
    private boolean createAndSaveTransaction(String userId, String txId, BigDecimal changeAmount, BigDecimal balanceAfterChange,
                                             String txType, String remark, String userType, String type) {
        log.info("开始保存交易记录，用户id{},业务id{},交易类型{}，用户类型{}", userId, txId, txType, userType);
        UserBalanceTransactionEntity transaction = new UserBalanceTransactionEntity();
        transaction.setUserId(userId);
        transaction.setTxId(txId);
        transaction.setChangeAmount(changeAmount);  // 微信单位为分
        transaction.setBalanceSnapshot(balanceAfterChange);
        transaction.setTxStatus(OrderConstants.TX_STATUS_SUCCESS);
        transaction.setTxType(txType);
        transaction.setRemark(remark);
        transaction.setUserType(userType);
        transaction.setType(type);
        boolean result = userBalanceTransactionService.save(transaction);
        log.info("保存交易结果：{}", result ? "成功" : "失败");
        return result;
    }

    //    @Async
    public void saveMessage(TransferRecord record) {
        log.info("开始发送转账消息 {}", record);
        String bizId = record.getId();

        ChatMessagesEntity chatMessagesEntity = new ChatMessagesEntity();

        chatMessagesEntity.setBizId(bizId);
        // 评论的不创建会话id了
        String conversationId = chatConversationService.getConversation(record.getFromUserId(), record.getToUserId()).getId();
        chatMessagesEntity.setConversationId(conversationId);
        chatMessagesEntity.setTime(LocalDateTime.now());
        chatMessagesEntity.setPostMessages("转账信息");
        chatMessagesEntity.setMsgStatus(ChatMessageConstant.MESSAGE_STATUS_UNREAD);
        chatMessagesEntity.setMessagesType(ChatMessageConstant.MESSAGE_TYPE_ACTIVITY_TRANSFER);
        chatMessagesEntity.setFormUserId(record.getFromUserId());
        chatMessagesEntity.setToUserId(record.getToUserId());
        chatMessagesEntity.setType(ChatMessageConstant.MESSAGE_TYPE_ACTIVITY_TRANSFER);
        chatMessagesService.save(chatMessagesEntity);
        // 发送消息
        // 更新会话最后聊天id
        chatConversationService.updateLastMessageId(conversationId, chatMessagesEntity.getId(), record.getFromUserId());

        // 构建响应JSON
        JSONObject resJson = buildResponseJson(record.getFromUserId(), chatMessagesEntity, record);
        JSONObject toResJson = buildResponseJson(record.getToUserId(), chatMessagesEntity, record);


        // 给某个用户发消息
        WebSocketChatService.sendMessageToUserId(record.getToUserId(), toResJson.toJSONString());
        WebSocketChatService.sendMessageToUserId(record.getFromUserId(), resJson.toJSONString());

        // 在重新发一个列表
        sendChatConversationList(record.getToUserId(), "0");
        sendChatConversationList(record.getFromUserId(), "1");
        log.info("转账发送消息完成");
    }

    private JSONObject buildResponseJson(String userId, ChatMessagesEntity entity, TransferRecord record) {
        JSONObject resJson = new JSONObject();
        ChatMessageVo vo = chatMessagesService.convertToDTO(entity);
        vo.setSender(entity.getFormUserId().equals(userId));
//        resJson.put("type", "send");
        resJson.put("message", vo);
        resJson.put("type", "transferMessage");
//        resJson.put("amt", record.getAmount());
//        if (record.getRemark() != null) {
//            resJson.put("remark", record.getRemark());
//        }
//        resJson.put("isTransfer", record.getToUserId().equals(userId));
//        resJson.put("transferTime", record.getCreateTime());
        resJson.put("conversationId", entity.getConversationId());
        return resJson;
    }

    protected void sendChatConversationList(String userId, String type) {
        List<ConversationDto> conversations = chatConversationService.getUserConversations(userId);
        JSONObject result = new JSONObject();
        result.put("type", "messageList");
        result.put("conversations", conversations);
        int unreadCount = 0;
        if ("0".equals(type)) {  // 收账方
            unreadCount = Math.toIntExact(chatMessagesService.count(new QueryWrapper<ChatMessagesEntity>().eq("to_user_id", userId).eq("msg_status", ChatMessageConstant.MESSAGE_STATUS_UNREAD)));
            log.info("收账方条数：{}", unreadCount);
        } else {// 转账方
            unreadCount = Math.toIntExact(chatMessagesService.count(new QueryWrapper<ChatMessagesEntity>().eq("form_user_id", userId).eq("msg_status", ChatMessageConstant.MESSAGE_STATUS_UNREAD)));
            log.info("转账方条数：{}", unreadCount);
        }
        result.put("unreadNum", unreadCount);
        WebSocketChatService.sendMessageToUserId(userId, result.toJSONString());
    }
}